﻿using System.Security.Claims;
using System.Text;
using System.Text.RegularExpressions;
using Common.Core;
using Domain.Infrastructure.Auth;
using Domain.Infrastructure.HttpContextUser;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using SqlSugar.Extensions;

namespace Domain.Infrastructure.ServiceExtensions
{
    /// <summary>
    /// 系统 授权服务 配置
    /// </summary>
    public static class AuthorizationSetup
    {
        public static IServiceCollection AddAuthorizationSetup(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));

            // 以下四种常见的授权方式。

            // 1、这个很简单，其他什么都不用做， 只需要在API层的controller上边，增加特性即可
            // [Authorize(Roles = "Admin,System")]


            // 2、这个和上边的异曲同工，好处就是不用在controller中，写多个 roles 。
            // 然后这么写 [Authorize(Policy = "Admin")]
            //services.AddAuthorization(options =>
            //{
            //    options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
            //});

            #region 参数
            //读取配置文件
            var symmetricKeyAsBase64 = ConfigurationUtil.App("Audience", "Secret");
            var keyByteArray = Encoding.UTF8.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            var Issuer = ConfigurationUtil.App("Audience", "Issuer");
            var Audience = ConfigurationUtil.App("Audience", "Audience");

            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);


            var permission = new List<PermissionItem>();

            // 角色与接口的权限要求参数
            var permissionRequirement = new PermissionRequirement(
                "/api/denied",// 拒绝授权的跳转地址（目前无用）
                permission,
                ClaimTypes.Role,//基于角色的授权
                Issuer,//发行人
                Audience,//听众
                signingCredentials,//签名凭据
                expiration: TimeSpan.FromDays(7)//接口的过期时间
                );
            #endregion
            // 3、自定义复杂的策略授权
            services.AddAuthorization(options =>
            {
                options.AddPolicy("Permission",
                         policy => policy.Requirements.Add(permissionRequirement));
            });


            //自我管理注册
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddScoped<IAuthorizationHandler, PermissionHandler>();
            services.AddSingleton(permissionRequirement);
            services.AddScoped<IUser, CustomUser>();
            return services;
        }
    }


    

    

    
}
